package com.zzj.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzj.base.Result;
import com.zzj.entity.*;
import com.zzj.model.dto.QueryListDTO;
import com.zzj.service.*;
import com.zzj.utils.JWTUtil;
import com.zzj.utils.QueryUtil;
import jakarta.annotation.Resource;
import org.apache.http.HttpHeaders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author zzj
 * @since 2023-02-10
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private IUserService userService;
    @Resource
    private INurseService nurseService;
    @Resource
    private IPatientService patientService;
    @Resource
    private IAdminService adminService;
    @Resource
    private RedisService redisService;


    @PostMapping("info")
    public Result info() {
        return Result.success();
    }


    @PostMapping("list")
    public Result list(@RequestBody @Validated QueryListDTO in) {

        QueryWrapper<User> queryWrapper = QueryUtil.paramsWrapper(in.getAndParams(), in.getOrParams(), in.getOrderParams());
        Page<User> userPage = new Page<>(in.getPageNo(), in.getPageSize());
        IPage<User> userIPage = userService.getBaseMapper().selectPage(userPage, queryWrapper);
        return Result.success(userIPage);
    }

    /**
     * 删除用户同时删除角色
     *
     * @param token
     * @param username
     * @return
     */
    @Transactional
    @PostMapping("delByUsername")
    public Result delByUsername(@RequestHeader(value = HttpHeaders.AUTHORIZATION) String token,
                                @RequestParam String username) {

        boolean admin = userService.isAdmin(token);
        if (!admin) return Result.error("无权限");
        User userByUsername = userService.findUserByUsername(username);
        if (userByUsername.getStatus() == 2) {
            LambdaQueryWrapper<Patient> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Patient::getUsername, username);
            patientService.remove(queryWrapper);
        } else if (userByUsername.getStatus() == 3) {
            LambdaQueryWrapper<Nurse> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Nurse::getUsername, username);
            nurseService.remove(queryWrapper);
        } else if (userByUsername.getStatus() == 5) {
            if (!userService.isAdmin(token)) return Result.error("无权限");
            LambdaQueryWrapper<Admin> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Admin::getUsername, username);
            adminService.remove(queryWrapper);
        }
        userService.removeById(userByUsername);
        return Result.success("删除成功");
    }


    /**
     * 关联更新必要表
     *
     * @param token
     * @param avatar
     * @return
     */
    @Transactional
    @PostMapping("updateAvatar")
    public Result updateAvatar(@RequestHeader(value = HttpHeaders.AUTHORIZATION) String token,
                               @RequestParam(value = "avatar") String avatar) {
        String username = JWTUtil.getUsername(token);

        User one = userService.getOne(Wrappers.<User>lambdaQuery()
                        .eq(User::getUsername, username),
                false);
        if (one != null) {
            userService.updateAvatar(one.getAvatar(), avatar);
            return Result.success("修改成功");
        }
        return Result.error("修改失败");
    }

    /**
     * 关联更新必要表
     * 用户名更新后重新登录 token
     * ************redis存储未改
     *
     * @param token
     * @param username
     * @return
     */
    @Transactional
    @PostMapping("updateUsername")
    public Result updateUsername(@RequestHeader(value = HttpHeaders.AUTHORIZATION) String token,
                                 @RequestParam(value = "username") String username) {
        String old = JWTUtil.getUsername(token);

        User one = userService            .getOne(Wrappers.<User>lambdaQuery()
                        .eq(User::getUsername, username),
                false);
        if (one != null) {
            return Result.error("修改失败，用户名已存在");
        }
        userService.updateUsername(old, username);
        return Result.success("修改成功");
    }

    /**
     * 注销账号
     *
     * @return
     */
    @Transactional
    @PostMapping("destroy")
    public Result destroy(@RequestHeader(value = HttpHeaders.AUTHORIZATION) String token,
                          @RequestParam("email") String email,
                          @RequestParam("code") String code) {
        //收验证码注销
        String username = JWTUtil.getUsername(token);
        Result result = redisService.verifyVerificationCode(email, code);
        if (result.getCode() != 0) {
            return result;
        }
        userService.lambdaUpdate()
                .eq(User::getUsername, username)
                .remove();
        patientService.lambdaUpdate()
                .eq(Patient::getUsername, username)
                .remove();
        nurseService.lambdaUpdate()
                .eq(Nurse::getUsername, username)
                .remove();
        adminService.lambdaUpdate()
                .eq(Admin::getUsername, username)
                .remove();
        return Result.success("账号注销成功");
    }

    @Transactional
    @PostMapping("destroyRedirect")
    public Result destroyRedirect(@RequestHeader(value = HttpHeaders.AUTHORIZATION) String token) {
        String username = JWTUtil.getUsername(token);
        User one = userService.findUserByUsername(username);
        if (one.getEmail() != null) {
            return Result.error("注销失败，邮箱已绑定");
        }
        userService.lambdaUpdate()
                .eq(User::getUsername, username)
                .remove();
        patientService.lambdaUpdate()
                .eq(Patient::getUsername, username)
                .remove();
        nurseService.lambdaUpdate()
                .eq(Nurse::getUsername, username)
                .remove();
        adminService.lambdaUpdate()
                .eq(Admin::getUsername, username)
                .remove();
        return Result.success("账号注销成功");
    }

    /**
     * 绑定邮箱
     * 验证
     *
     * @param token
     * @param email
     * @return
     */
    @Transactional
    @PostMapping("bindEmail")
    public Result bindEmail(@RequestHeader(value = HttpHeaders.AUTHORIZATION) String token,
                            @RequestParam("email") String email,
                            @RequestParam("code") String code) {

        String username = JWTUtil.getUsername(token);
        Result result = redisService.verifyVerificationCode(email, code);
        if (result.getCode() != 0) {
            return result;
        }
        User one = userService.findUserByEmail(email);
        if (one != null) {
            return Result.error("绑定失败，该邮箱已被绑定");
        }
        userService.setUserEmail(username, email);
        return Result.success("绑定成功");
    }

    @Transactional
    @PostMapping("unBindEmail")
    public Result unBindEmail(@RequestHeader(value = HttpHeaders.AUTHORIZATION) String token,
                              @RequestParam("email") String email,
                              @RequestParam("code") String code) {

        String username = JWTUtil.getUsername(token);
        Result result = redisService.verifyVerificationCode(email, code);
        if (result.getCode() != 0) {
            return result;
        }
        userService.setUserEmail(username, null);
        return Result.success("解绑成功");
    }

    @Transactional
    @PostMapping("setPassword")
    public Result setPassword(@RequestHeader(value = HttpHeaders.AUTHORIZATION) String token,
                              @RequestParam("email") String email,
                              @RequestParam("code") String code,
                              @RequestParam("password") String password) throws Exception {

        String username = JWTUtil.getUsername(token);
        Result result = redisService.verifyVerificationCode(email, code);
        if (result.getCode() != 0) {
            return result;
        }
        userService.setUserPassword(username, password);
        return Result.success("设置成功");
    }

    @Transactional
    @PostMapping("updatePassword")
    public Result updatePassword(@RequestHeader(value = HttpHeaders.AUTHORIZATION) String token,
                                 @RequestParam("oldPassword") String oldPassword,
                                 @RequestParam("newPassword") String newPassword) throws Exception {

        String username = JWTUtil.getUsername(token);


        User one = userService.findUserByUsernamePassword(username, oldPassword);
        if (one == null) {
            return Result.error("旧密码错误");
        }
        userService.setUserPassword(username, newPassword);
        return Result.success("修改成功");
    }


}
